package portfolio.stock.analize;

import java.awt.*;
import java.applet.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.Graphics2D;
import java.awt.image.RenderedImage;
import java.awt.image.BufferedImage;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.event.*;
import java.util.Vector;

/********************************************************/
public class em_graph extends JPanel //implements ActionListener
{
     private int         RECTSIDE_X;
     private int         RECTSIDE_Y;
     private double [][] dDataIn = null;
     private int         iTerm;
     private int         iTrainLen;

     private double dMin;
     private double dMax;
     private Vector vTimeLine;
 
/********************************************************/
  public em_graph (
                    double[][] DataParam, 
                    Vector vTimeLineParam, 
                    int iTermParam, 
                    int iTrainLenParam, 
                    int iSideX, 
                    int iSideY, 
                    String sName)
  {
      super ();
      
        dDataIn   = DataParam;
        iTerm     = iTermParam;
        iTrainLen = iTrainLenParam;
        vTimeLine = vTimeLineParam;
        
        RECTSIDE_X = iSideX;
        RECTSIDE_Y = iSideY;
        
        double [] dMinMax = getMinMax (DataParam, 0);
        dMax = dMinMax [1];
        dMin = dMinMax [0];        

        this.setPreferredSize(new Dimension(RECTSIDE_X, RECTSIDE_Y));

        this.setBackground(Color.white);
        
        setVisible (true);
  }
/********************************************************/
  void plotCoordinatePlane (Graphics2D g2, int iXorig, int iYorig, int iWidth, int iHeight)
  {	
        int	i;
        double	scaleX, 
                scaleY;
        
        int RECTSIDE_x = iWidth;
        int RECTSIDE_y = iHeight;

        //System.out.println ("Min: " +dMin + " Max: " + dMax);
        g2.drawRect(iXorig, iYorig, RECTSIDE_x -(2 * iXorig), RECTSIDE_y -(2 *iYorig));
  }  
/********************************************************/
  void plotTimeSeries (Graphics2D g2, int iXorig, int iYorig, int iWidth, int iHeight, double [][] dTimeSeries, int iVectX)
  {	
        int	i;
        double	scaleX, 
                scaleY;
        
        int RECTSIDE_x = iWidth -2 * iXorig;
        int RECTSIDE_y = iHeight -2 * iYorig;

        int dataInput_N = dTimeSeries.length;
        scaleX = (((double)RECTSIDE_x) / dataInput_N);
        scaleY = (RECTSIDE_y) / (dMax - dMin);

        for(i=0; i < dataInput_N; i++) {
            double dY = (double) dMin;
            if (dTimeSeries [i][iVectX] > 0)
                dY = dTimeSeries [i][iVectX];
            if (dTimeSeries [i][iVectX] > dMax)
                dY = dMax;
            
             if (i != 0) {
                double dY_1 = (double) dMin;
                if (dTimeSeries [i -1][iVectX] > 0)
                    dY_1 = dTimeSeries [i -1][iVectX];
                if (dTimeSeries [i -1][iVectX] > dMax)
                    dY_1 = dMax;                 
                g2.drawLine((int)((i-1)*scaleX + iXorig), 
                            (int)(RECTSIDE_y + iYorig - (dY_1 -dMin) * scaleY),
                            (int)((i)*scaleX + iXorig), 
                            (int)(RECTSIDE_y + iYorig - (dY -dMin) * scaleY));
             }
         }
  }
/********************************************************/
  int plotVerticalLine (Graphics2D g2, int iXorig, int iYorig, int iWidth, int iHeight, int iTrainLimit, int dataInput_N)
  {	
        int	i;
        double	scaleX, 
                scaleY;
        
        //Dimension panelDimension = getSize (null);
        int RECTSIDE_x = iWidth - 2 * iXorig;
        int RECTSIDE_y = iHeight -2 * iYorig;

        //int dataInput_N = dTimeSeries.length;
        scaleX = (((double)RECTSIDE_x) / dataInput_N);
        scaleY = (RECTSIDE_y - 10) / (dMax - dMin);

        g2.drawLine((int)(iTrainLimit * scaleX + iXorig), 
                    (int)(iYorig),
                    (int)(iTrainLimit * scaleX + iXorig), 
                    (int)(RECTSIDE_y + iYorig));
        
        return (int)(iTrainLimit * scaleX + iXorig);
  }  
/********************************************************/
  int plotHorizontalLine (Graphics2D g2, int iXorig, int iYorig, int iWidth, int iHeight, double dY_1)
  {	
        int	i;
        double	scaleX, 
                scaleY;
        
        int RECTSIDE_x = iWidth - 2 * iXorig;
        int RECTSIDE_y = iHeight -2 * iYorig;

        //scaleX = (((double)RECTSIDE_x) / dataInput_N);
        scaleY = (RECTSIDE_y - 10) / (dMax - dMin);

        g2.drawLine(iXorig, 
                    (int)(RECTSIDE_y + iYorig - (dY_1 -dMin) * scaleY),
                    iXorig + RECTSIDE_x, 
                    (int)(RECTSIDE_y + iYorig - (dY_1 -dMin) * scaleY));
        
        return (int)(RECTSIDE_y + iYorig - (dY_1 -dMin) * scaleY);
  }    
/********************************************************/
    public void paintComponent(Graphics g) 
    {   
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        
        Dimension panelDimension = getSize (null);
        drawGraph (g2, 35, 30, (int)panelDimension.getWidth (), (int)panelDimension.getHeight ());

    }
/********************************************************/
    public double [] getMinMax (double[][] Data, int iVect)
    {
    int n,
        i,
        j;
    Data = Data;
    int N    = Data.length;
    int d    = Data[0].length;

    double [] dMinMax   = new double[2];
    //Max   = new double[2];

    dMinMax [0] = Data[0][iVect];
    dMinMax [1] = Data[0][iVect];

    for(n=1; n < N; n++) {
        if(dMinMax[0] > Data[n][iVect] && Data[n][iVect] != 0) 
            dMinMax [0] = Data[n][iVect]; 
        else  if(dMinMax[1] < Data[n][iVect]) 
            dMinMax [1] = Data[n][iVect];
    }

    return dMinMax;  
    } /* end getMinMax */ 
    /***********************************************************/
    public void drawGraph (Graphics2D g2, int iXorig, int iYorig, int iWidth, int iHeight)
    {
        int RECTSIDE_y = iHeight - 2 * iYorig;
        
        g2.setBackground (Color.WHITE); //white);
        g2.setColor (Color.BLACK);
        plotCoordinatePlane (g2, iXorig, iYorig, iWidth, iHeight);

        plotTimeSeries (g2, iXorig, iYorig, iWidth, iHeight, dDataIn, 0);
        g2.setColor(Color.GREEN);
        plotTimeSeries (g2, iXorig, iYorig, iWidth, iHeight, dDataIn, 1);
        
        g2.setColor (Color.GRAY);
        int iYLast = plotHorizontalLine (g2, iXorig, iYorig, iWidth, iHeight, dDataIn[dDataIn.length -1][1]);
        
        g2.setColor (Color.RED);
        int iXTrain = plotVerticalLine (g2, iXorig, iYorig, iWidth, iHeight, iTrainLen, dDataIn.length);
        g2.setColor (Color.CYAN);
        int iXBegin = plotVerticalLine (g2, iXorig, iYorig, iWidth, iHeight, dDataIn.length - iTerm, dDataIn.length); 
        g2.setColor(Color.BLACK);
        int iXEnd   = plotVerticalLine (g2, iXorig, iYorig, iWidth, iHeight, dDataIn.length, dDataIn.length);
        // Y axe
        g2.drawString (Integer.toString ((int)dMax),                            1, iYorig);
        g2.drawString (Integer.toString ((int)dMin),                            1, iYorig + RECTSIDE_y);
        g2.drawString (Integer.toString ((int)dDataIn [dDataIn.length -1] [1]), 1, iYLast);

        // X axe
        g2.drawString (vTimeLine.get(0).toString(),                      iXorig  -32, iYorig + RECTSIDE_y +23);
        g2.drawString (vTimeLine.get(iTrainLen).toString(),              iXTrain -32, iYorig + RECTSIDE_y +12);
        g2.drawString (vTimeLine.get(dDataIn.length - iTerm).toString(), iXBegin -32, iYorig + RECTSIDE_y +23);
        g2.drawString (vTimeLine.get(dDataIn.length-1).toString(),       iXEnd   -32, iYorig + RECTSIDE_y +12);
        
        g2.drawString (Integer.toString (0),                             iXorig  , 20);
        g2.drawString (Integer.toString (iTrainLen),                     iXTrain , 20);
        g2.drawString (Integer.toString (dDataIn.length - iTerm),        iXBegin , 20);
        g2.drawString (Integer.toString (dDataIn.length-1),              iXEnd   , 20); 
    }
    /****************************************************************/
    public RenderedImage drawJpgGraphic (int iWidth, int iHeight)
    {
        BufferedImage bufferedImage = new BufferedImage(iWidth, iHeight, BufferedImage.TYPE_INT_RGB);
    
        // Create a graphics contents on the buffered image
        Graphics2D g2d = bufferedImage.createGraphics();

        g2d.setColor (Color.WHITE);
        g2d.fillRect(0, 0, iWidth, iHeight);        
        
        drawGraph (g2d, 25, 30, iWidth, iHeight);
    
        // Graphics context no longer needed so dispose it
        g2d.dispose();
        
        return bufferedImage;
    }
} /* end class m_graph */

  
